// Infrastructure/UnitOfWork.cs
using Microsoft.EntityFrameworkCore;
using UniversalAdmin.Domain.Interfaces;
using UniversalAdmin.Domain.Repositories;
using UniversalAdmin.Infrastructure.Data;
using UniversalAdmin.Infrastructure.Repositories;

namespace UniversalAdmin.Infrastructure
{
  public class UnitOfWork : IUnitOfWork
  {
    private readonly UniversalAdminDbContext _context;
    private bool _disposed;

    public UnitOfWork(UniversalAdminDbContext context)
    {
      _context = context;
    }

    public IUserRepository UserRepository => new UserRepository(_context);
    public IRoleRepository RoleRepository => new RoleRepository(_context);
    public IMenuRepository MenuRepository => new MenuRepository(_context);
    public ISystemConfigRepository SystemConfigRepository => new SystemConfigRepository(_context);
    public IFileRepository FileRepository => new FileRepository(_context);
    public IOperationLogRepository OperationLogRepository => new OperationLogRepository(_context);
    public IRefreshTokenRepository RefreshTokenRepository => new RefreshTokenRepository(_context);
    public IArticleRepository Articles => new ArticleRepository(_context);

    public async Task BeginTransactionAsync()
    {
      await _context.Database.BeginTransactionAsync();
    }

    public async Task CommitAsync()
    {
      await _context.Database.CommitTransactionAsync();
    }

    public async Task RollbackAsync()
    {
      await _context.Database.RollbackTransactionAsync();
    }

    public async Task<int> SaveChangesAsync()
    {
      return await _context.SaveChangesAsync();
    }

    public async Task ExecuteSqlRawAsync(string sql, params object[] parameters)
    {
      await _context.Database.ExecuteSqlRawAsync(sql, parameters);
    }

    protected virtual void Dispose(bool disposing)
    {
      if (!_disposed)
      {
        if (disposing)
        {
          _context.Dispose();
        }
        _disposed = true;
      }
    }

    public void Dispose()
    {
      Dispose(true);
      GC.SuppressFinalize(this);
    }
  }
}